﻿/* ColorReduce.cpp
 * 
 * Copyright (C) 2020, 2021 Yuan LI
 * email:18069211@qq.com
 * https://blog.csdn.net/liyuanbhu
 * 
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or (at
 * your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 */

#include "opencv2/core.hpp"

void colorReduce(cv::Mat &image, int div=64)
{
    int nl = image.rows; // number of lines
    // total number of elements per line
    int nc = image.cols * image.channels();
    for (int j = 0; j < nl; j++)
    {
        // get the address of row j
        uchar* data= image.ptr<uchar>(j);
        for (int i = 0; i < nc; i++)
        {
            // process each pixel ---------------------
            data[i]= data[i] / div * div + div / 2;
            // end of pixel processing ----------------
        }
    } // end of line
}

void colorReduce2(cv::Mat &image, int div=64)
{
    int nl = image.rows; // number of lines
    int nc = image.cols * image.channels();
    if (image.isContinuous())
    {
        // then no padded pixels
        nc = nc * nl;
        nl = 1; // it is now a 1D array
    }
    // this loop is executed only once
    // in case of continuous images
    for (int j = 0; j < nl; j++)
    {
        uchar* data = image.ptr<uchar>(j);
        for (int i = 0; i < nc; i++)
        {
            // process each pixel ---------------------
            data[i] = data[i] / div * div + div / 2;
            // end of pixel processing ----------------
        } // end of line
    }
}

void colorReduce3(cv::Mat &image, int div=64)
{
    // obtain iterator at initial position
    cv::Mat_<cv::Vec3b>::iterator it = image.begin<cv::Vec3b>();
    // obtain end position
    cv::Mat_<cv::Vec3b>::iterator itend = image.end<cv::Vec3b>();
    // loop over all pixels
    for ( ; it!= itend; ++it)
    {
        // process each pixel ---------------------
        (*it)[0] = (*it)[0] / div * div + div / 2;
        (*it)[1] = (*it)[1] / div * div + div / 2;
        (*it)[2] = (*it)[2] / div * div + div / 2;
    }
}
